package org.bjf.aop;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bjf.exception.CommMsgCode;
import org.bjf.exception.ServiceException;
import org.bjf.modules.core.web.core.LoginInfo;
import org.bjf.modules.core.web.core.ThreadContext;
import org.bjf.modules.user.enums.UserRedisKey;
import org.bjf.utils.ExceptionAssert;
import org.bjf.utils.RedisUtil;
import org.bjf.utils.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * 权限校验拦截器
 *
 * @author bjf
 */
@Component
@Slf4j
public class AdminInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisUtil redis;

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
            // token校验
            String accessToken = getAccessToken(request);
            if (StringUtils.isBlank(accessToken) || !TokenUtil.verifyToken(accessToken)) {
                log.error("invalid token:{}", accessToken);
                throw new ServiceException(CommMsgCode.UNAUTHORIZED);
            }
            LoginInfo loginInfo = getLoginInfo(accessToken);
            // 登录用户信息放到ThreadLocal
            loginInfo.setLastTime(new Date());
            ThreadContext.setLoginInfo(loginInfo);

            log.info("admin loginInfo：" + JSON.toJSONString(loginInfo));

            // permission权限校验
            /*HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            Permission permission = method.getDeclaringClass().getAnnotation(Permission.class);

            if (permission != null) {
                PermissionMethod permissionMethod = PermissionMethod.get(method.getName());
                boolean hasPermit = rolePermService
                        .hasControllerPermission(loginInfo.getUserId(), permission.resSn(),
                                permissionMethod);
                ExceptionAssert.isTrue(hasPermit, CommMsgCode.FORBIDDEN, "没有权限，请联系管理员");
            }*/
        }

        return Boolean.TRUE;
    }

    private LoginInfo getLoginInfo(String accessToken) {
        // redis取登录用户信息
        String userKey = UserRedisKey.TOKEN_ADMIN.as(accessToken);
        LoginInfo loginInfo = redis.getObj(userKey);
        ExceptionAssert.notNull(loginInfo, CommMsgCode.UNAUTHORIZED);
        // 更新reids过期时间
        redis.setObj(userKey, loginInfo, 60 * 30);

        return loginInfo;
    }

    private String getAccessToken(HttpServletRequest request) {
        String accessToken = request.getHeader("x-admin-token");
        if (StringUtils.isBlank(accessToken)) {
            accessToken = request.getParameter("x-admin-token");
        }
        return accessToken;
    }
}
